import json
import os
from datetime import datetime, date
from pathlib import Path
import threading
import time
import glob


class LogManager:
    def __init__(self, config):
        self.config = config
        self.log_directory = Path(config.get('log_directory', './logs'))
        self.organization = config.get('organization', 'DefaultOrg')
        self.current_date = None
        self.current_log_file = None
        self.device_id = None
        self._lock = threading.Lock()
        self._static_info_written_today = False

        # 创建日志目录
        self.log_directory.mkdir(parents=True, exist_ok=True)

    def get_device_id(self):
        return self.device_id

    def _get_log_filename(self, target_date=None):
        """生成日志文件名"""
        if target_date is None:
            target_date = date.today()

        if self.device_id is None:
            raise ValueError("设备ID尚未设置，请先采集静态信息")

        date_str = target_date.strftime("%Y%m%d")
        filename = f"{date_str}_{self.device_id}_{self.organization}.jsonl"
        return self.log_directory / filename

    def _find_today_log_files(self, target_date=None):
        """查找今天的日志文件（按日期前缀）"""
        if target_date is None:
            target_date = date.today()

        date_str = target_date.strftime("%Y%m%d")
        pattern = f"{date_str}_*_{self.organization}.jsonl"

        search_pattern = str(self.log_directory / pattern)
        matching_files = glob.glob(search_pattern)

        return [Path(f) for f in matching_files]

    def _check_static_info_exists_today(self, target_date=None):
        """检查今天是否已经有静态信息"""
        matching_files = self._find_today_log_files(target_date)

        if not matching_files:
            return False

        # 检查文件中是否包含静态信息（现在直接检查静态信息结构）
        for log_file in matching_files:
            try:
                with open(log_file, 'r', encoding='utf-8') as f:
                    for line in f:
                        try:
                            entry = json.loads(line.strip())
                            # 检查是否为静态信息（包含系统基本信息的结构）
                            if self._is_static_info(entry):
                                # 如果找到了静态信息，更新设备ID和当前日志文件
                                if self.device_id is None:
                                    self.device_id = self._extract_device_id(entry)
                                    print(f"从现有日志文件中获取设备ID: {self.device_id}")
                                self.current_log_file = log_file
                                return True
                        except json.JSONDecodeError:
                            continue
            except Exception as e:
                print(f"读取日志文件失败 {log_file}: {e}")
                continue

        return False

    def _is_static_info(self, entry):
        """判断是否为静态信息"""
        # 静态信息通常包含这些字段
        static_indicators = ['baseboard_manufacturer', 'baseboard_product_name', 'baseboard_version', 'baseboard_serial_number', 'system_manufacturer']

        if isinstance(entry, dict):
            # 检查是否包含静态信息的关键字段
            found_indicators = sum(1 for indicator in static_indicators if indicator in entry)
            return found_indicators >= 2  # 至少包含2个静态信息字段

        return False

    def _write_log_entry_to_file(self, log_entry, file_path):
        """立即写入单条日志到文件"""
        try:
            # 确保目录存在
            file_path.parent.mkdir(parents=True, exist_ok=True)

            # 直接写入原始数据，不包装JSON结构
            with open(file_path, 'a', encoding='utf-8') as f:
                f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
                f.flush()  # 立即刷新到磁盘
                os.fsync(f.fileno())  # 强制操作系统写入磁盘
            return True
        except Exception as e:
            print(f"写入日志文件失败: {e}")
            return False

    def _prepare_log_file(self):
        """准备日志文件路径"""
        current_date = date.today()

        # 检查是否需要切换到新日期
        if self.current_date != current_date:
            print(f"切换到新日期: {current_date}")
            self.current_date = current_date
            self._static_info_written_today = False

            # 如果有设备ID，直接构造文件路径
            if self.device_id is not None:
                self.current_log_file = self._get_log_filename(current_date)
                if self.current_log_file.exists():
                    self._static_info_written_today = True
                    print(f"继续使用现有日志文件: {self.current_log_file}")
                else:
                    print(f"准备创建新日志文件: {self.current_log_file}")

        # 如果还没有确定日志文件，且有设备ID，则创建文件路径
        if self.current_log_file is None and self.device_id is not None:
            self.current_log_file = self._get_log_filename(current_date)
            print(f"准备创建新日志文件: {self.current_log_file}")

    def write_static_info(self, device_info):
        """写入设备静态信息 - 立即写入"""
        with self._lock:
            # 提取设备ID
            if self.device_id is None:
                self.device_id = self._extract_device_id(device_info)
                print(f"设备ID: {self.device_id}")

            # 准备日志文件
            self._prepare_log_file()

            # 直接写入静态信息，不包装
            if self.current_log_file:
                success = self._write_log_entry_to_file(device_info, self.current_log_file)
                if success:
                    self._static_info_written_today = True
                    print(f"静态信息已写入日志: {self.current_log_file.name}")
                else:
                    print("静态信息写入失败")
            else:
                print("错误: 无法确定日志文件路径")

    def write_dynamic_info(self, device_state, is_summary=False):
        """写入设备动态信息 - 立即写入"""
        with self._lock:
            if self.device_id is None:
                print("警告: 设备ID未设置，无法写入动态信息")
                return

            # 准备日志文件
            self._prepare_log_file()

            # 直接写入动态信息，不包装
            if self.current_log_file:
                success = self._write_log_entry_to_file(device_state, self.current_log_file)
                if success:
                    type_name = "动态信息摘要" if is_summary else "动态信息"
                    print(f"[{datetime.now().strftime('%H:%M:%S')}] {type_name}已写入日志")
                else:
                    print("动态信息写入失败")
            else:
                print("错误: 无法确定日志文件路径")

    def _extract_device_id(self, device_info):
        """从静态信息中提取设备ID"""
        if isinstance(device_info, dict):
            # 获取主板序列号字段作为id
            if 'baseboard_serial_number' in device_info:
                return str(device_info['baseboard_serial_number'])

        # 如果都没有，生成一个基于时间戳和随机数的ID
        import random
        timestamp = int(time.time())
        random_num = random.randint(1000, 9999)
        return f"device_{timestamp}_{random_num}"

    def need_static_info_today(self):
        """检查今天是否需要写入静态信息"""
        with self._lock:
            current_date = date.today()

            # 如果今天还没写过静态信息
            if not self._static_info_written_today:
                # 检查文件系统中是否已存在今天的静态信息
                return not self._check_static_info_exists_today(current_date)

            return False

    def get_today_log_files(self):
        """获取今天的所有日志文件"""
        return self._find_today_log_files()

    def get_current_log_file(self):
        """获取当前日志文件路径"""
        return self.current_log_file

    def test_write_access(self):
        """测试写入权限"""
        test_file = self.log_directory / "test_write.tmp"
        try:
            with open(test_file, 'w') as f:
                f.write("test")
            test_file.unlink()  # 删除测试文件
            return True
        except Exception as e:
            print(f"写入权限测试失败: {e}")
            return False
